package com.qf.controller;

import com.qf.pojo.Order;
import com.qf.pojo.Result;
import com.qf.pojo.User;
import com.qf.service.OrderService;
import com.qf.service.impl.OrderServiceStub;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {

    /*
        ① 当服务消费者程序启动时，dubbo扫描到这个注解，会到注册中心拉取之前提供方注册的信息（协议、ip、端口、接口信息）
        会在服务消费方基于动态代理的方式实现OrderService接口的代理对象。代理对象的内部实现方式是基于netty发起远程访问

        ② 会将这个接口的代理对象添加到当前程序的spring容器中,所以后续也可以通过Autowired注入
     */

    /*
        集群容错：
            Failover 当访问集群中一台机器失败后，会重试访问另一台机器，直到成功 （没有幂等性问题建议使用）
            Failfast 只发起一次调用，如果失败，直接失败 （存在幂等性问题建议使用）

            Failsafe 失败不报异常
            Failback 当访问一台机器失败，不会切换机器访问，而是一直重试这台机器，直到成功
            Forking  访问多台机器，只要有一台成功就认为成功
            Broadcast 访问多台机器，只要有一台访问失败，就失败

        负载均衡：
            random         随机
            **roundrobin     权重轮询（比如一台机器权重配置的是10，另一台机器权重配置的是20.那么在访问时，10的那台访问1次，20那台访问2次）
            leastactive    最少活跃数，计录某台机器是否有访问失败或者访问超时问题，如果有，那么后续请求尽量不给到这台机器
     */
    @Reference(version = "1.0",
            cluster = "failfast",
            loadbalance = "roundrobin",
            stub = "com.qf.service.impl.OrderServiceStub",
            mock = "com.qf.service.impl.OrderServiceMock"
    )  //导入的是appach下的Reference注解
    private OrderService orderService;

    @GetMapping("/{id}")
    public Result findById(@PathVariable("id") Integer id){
        User user = new User();
        user.setId(id);
        user.setUsername("zhangsan" + id);
        //订单（通过订单服务，查询用户的订单）
        List<Order> orders = orderService.findByUid(id);
        user.setOrders(orders);

        return Result.success("查询成功",user);
    }

}
